<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Import Namespace="System.Xml" %>
<%@ Import Namespace="System.IO" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>ViewState Decoder</title>
</head>
<body>
    <form id="form1" runat="server">
    <div style="text-align:center">
        ViewState:<br /><br />
        <asp:TextBox Rows="20" Columns="100" ID="vs" TextMode="MultiLine" runat="server" ></asp:TextBox><br />
        <asp:Button ID="pst" runat="server" Text="Submit"/>&nbsp;
        <INPUT id="Clear" type="button" onclick="document.form1.vs.value = '';" value="Clear"><br />
    </div>
    <br />
    <div style="text-align:left">
        <b><asp:Label ID="v1" runat="server" Visible="false" text="VIEWSTATE SIZE:" /></b>&nbsp;<asp:Label ID="vwSize" runat="server" />
    </div>
    <br />
    <div style="text-align:left">
            <asp:Label id="res" runat="server" />
    </div>            
    </form>
</body>
<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        if (IsPostBack)
        {
            XmlDocument doc = Decode(vs.Text);
            StringBuilder sb = new StringBuilder();
            DumpXml(doc.DocumentElement, sb, 0);
            //res.Text = HttpUtility.HtmlEncode( doc.InnerText );
            v1.Visible = true;
            vwSize.Text = vs.Text.Length.ToString();
            res.Text = sb.ToString();
        }
    }
    
    public static XmlDocument Decode(string data)
    {
        LosFormatter formatter = new LosFormatter();
        XmlDocument document;
        object o = formatter.Deserialize(data);
        XmlDocument dom = BuildXml(o, out document);
        return dom;
    }
    public static XmlDocument BuildXml(object tree, out XmlDocument controlstateDom)
    {
        XmlDocument dom = new XmlDocument();
        controlstateDom = new XmlDocument();
        dom.AppendChild(dom.CreateElement("viewstate"));
        controlstateDom.AppendChild(controlstateDom.CreateElement("controlstate"));
        BuildElement(dom, dom.DocumentElement, tree, ref controlstateDom);
        return dom;
    }

    private static string GetShortTypename(object obj)
    {
        string str = obj.GetType().ToString();
        return XmlConvert.EncodeName( str.Substring(str.LastIndexOf(".") + 1));
    }

    public static void DumpXml(XmlNode node, StringBuilder sb, int tabsCouter)
    {
        if (!String.IsNullOrEmpty(node.Value))
        {
            for (int i = 0; i < tabsCouter; i++)
            {
                sb.Append("&nbsp;");
            }
            sb.Append(node.Value); sb.Append("<br/>");
        }
        foreach (XmlNode nd in node.ChildNodes)
        {
            DumpXml(nd, sb, tabsCouter + 1);
        }
    }

    private static void BuildElement(XmlDocument dom, XmlElement elem, object treeNode, ref XmlDocument controlstateDom)
    {
        if (treeNode != null)
        {
            XmlElement element;
            Type type = treeNode.GetType();
            if (type == typeof(Triplet))
            {
                element = dom.CreateElement(GetShortTypename(treeNode));
                elem.AppendChild(element);
                BuildElement(dom, element, ((Triplet)treeNode).First, ref controlstateDom);
                BuildElement(dom, element, ((Triplet)treeNode).Second, ref controlstateDom);
                BuildElement(dom, element, ((Triplet)treeNode).Third, ref controlstateDom);
            }
            else if (type == typeof(Pair))
            {
                element = dom.CreateElement(GetShortTypename(treeNode));
                elem.AppendChild(element);
                BuildElement(dom, element, ((Pair)treeNode).First, ref controlstateDom);
                BuildElement(dom, element, ((Pair)treeNode).Second, ref controlstateDom);
            }
            else if (type == typeof(ArrayList))
            {
                element = dom.CreateElement(GetShortTypename(treeNode));
                elem.AppendChild(element);
                foreach (object obj2 in (ArrayList)treeNode)
                {
                    BuildElement(dom, element, obj2, ref controlstateDom);
                }
            }
            else if (treeNode is Array)
            {
                element = dom.CreateElement("Array");
                elem.AppendChild(element);
                foreach (object obj3 in (Array)treeNode)
                {
                    BuildElement(dom, element, obj3, ref controlstateDom);
                }
            }
            else if (treeNode is HybridDictionary)
            {
                element = controlstateDom.CreateElement(GetShortTypename(treeNode));
                controlstateDom.DocumentElement.AppendChild(element);
                foreach (object obj4 in (HybridDictionary)treeNode)
                {
                    BuildElement(controlstateDom, element, obj4, ref controlstateDom);
                }
            }
            else if (treeNode is DictionaryEntry)
            {
                element = dom.CreateElement(GetShortTypename(treeNode));
                elem.AppendChild(element);
                DictionaryEntry entry = (DictionaryEntry)treeNode;
                BuildElement(dom, element, entry.Key, ref controlstateDom);
                DictionaryEntry entry2 = (DictionaryEntry)treeNode;
                BuildElement(dom, element, entry2.Value, ref controlstateDom);
            }
            else
            {
                element = dom.CreateElement(GetShortTypename(treeNode));
                if (type == typeof(IndexedString))
                {
                    element.InnerText = ((IndexedString)treeNode).Value;
                }
                else
                {
                    element.InnerText = treeNode.ToString();
                }
                elem.AppendChild(element);
            }
        }
    }
</script>
</html>
